/*
 * Copyright (C) 2017 Fabian Terhorst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file kt in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.fabianterhorst.isometric;

import io.reactivex.rxjava3.annotations.NonNull;

/**
 * Vector.
 *
 * @since 2021-03-11
 */

public class Vector {
    /**
     * To get class name
     */
    private static final String TAG = Shape.class.getName();

    /**
     * double
     */
    protected double i;

    /**
     * double
     */
    protected double j;

    /**
     * double
     */
    protected double k;

    /**
     * Constructor
     *
     * @param i {@link double}
     * @param j {@link double}
     * @param k {@link double}
     */
    public Vector(double i, double j, double k) {
        this.i = i;
        this.j = j;
        this.k = k;
    }

    /**
     * fromTwoPoints
     * @param p1 {@link Point}
     * @param p2 {@link Point}
     * @return Vector
     */
    @NonNull
    public static Vector fromTwoPoints(Point p1, Point p2) {
        return new Vector(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
    }

    /**
     * crossProduct
     * @param v1 {@link Vector}
     * @param v2 {@link Vector}
     * @return Vector
     */
    @NonNull
    public static Vector crossProduct(Vector v1, Vector v2) {
        double i = v1.j * v2.k - v2.j * v1.k;
        double j = -1 * (v1.i * v2.k - v2.i * v1.k);
        double k = v1.i * v2.j - v2.i * v1.j;

        return new Vector(i, j, k);
    }

    /**
     * dotProduct
     * @param v1 {@link Vector}
     * @param v2 {@link Vector}
     * @return point
     */
    public static double dotProduct(Vector v1, Vector v2) {
        return v1.i * v2.i + v1.j * v2.j + v1.k * v2.k;
    }

    /**
     * magnitude
     * @return sqrt
     */
    public double magnitude() {
        return Math.sqrt(this.i * this.i + this.j * this.j + this.k * this.k);
    }

    /**
     * normalize
     * @return this
     */
    public Vector normalize() {
        double magnitude = this.magnitude();

        /**
         * If the magnitude is 0 then return the zero vector instead of dividing by 0
         */
        if (magnitude == 0) {
            return new Vector(0, 0, 0);
        }
        this.i = this.i / magnitude;
        this.j = this.j / magnitude;
        this.k = this.k / magnitude;
        return this;
    }
}
